package com.uxsino.simo.connections;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 主要用于清理未被正确关闭或者销毁的对象。
 * @ClassName ConnectionCleaner
 * @Description TODO
 * @Author <a href="mailto:royrxc@gmail.com">Administrator</a>
 * @Daate 2019/6/26 10:56
 **/
public class ConnectionCleaner{
    private static final Logger LOG = LoggerFactory.getLogger(ConnectionCleaner.class);
    private static final ConcurrentHashMap<IConnection, Long> BUFFER = new ConcurrentHashMap<>();
    //30 分钟过期
    public static final Long EXPIRED_MS = 30 * 60 * 1000L;
    //30 分钟过期
    public static final Long CLEAN_MS = 60 * 1000L;

    public static final Thread RUNNER = new Thread(()->{
        while (true){
            BUFFER.entrySet().parallelStream().filter((k)-> k.getValue() == null || new Long(System.currentTimeMillis()).compareTo(k.getValue()) >= 0).forEach(itm->{
                try {
                    itm.getKey().close();
                }catch (Exception e){

                }
                BUFFER.remove(itm.getKey());
            });
            LOG.info("[Connection - clean]: remained: " + BUFFER.size());
            try {
                TimeUnit.MILLISECONDS.sleep(CLEAN_MS);
            }catch (Exception e){}
        }
    });
    static {
        //设置为守护进程
        RUNNER.setDaemon(true);
        RUNNER.start();
    }

    public static void push(IConnection conn){
        push(conn, EXPIRED_MS);
    }

    public static void push(IConnection conn, long ms){
        BUFFER.put(conn, ms+ System.currentTimeMillis());
    }

    public static void remove(IConnection  conn){
        BUFFER.remove(conn);
    }

    public static Map<String, Integer> satistic(){
        Map<String, Integer> result = new ConcurrentHashMap<>();

        BUFFER.entrySet().parallelStream().forEach(itm->{
            String name = itm.getKey().getClass().getName();
            synchronized (result){
                Integer i = result.get(name);
                i = i != null? i+1 : 1;
                result.put(name, i);
            }
        });


        return result;
    }

    public static int size(){
        return BUFFER.size();
    }
}


